use std::path::Path;

use bc_base::{TransactionId, transaction::TransactionIndexNode};
use bc_db::DBError;

use crate::{DbHashMap, inner_storage::StorageBase};

#[derive(Debug)]
pub(crate) struct TransactionIndexStorage {
    index_db: StorageBase<TransactionId, TransactionIndexNode>,
}

impl TransactionIndexStorage {
    pub(crate) fn new(path: &Path) -> Result<Self, DBError> {
        let path = crate::get_transactions_index_db_path(path);
        tracing::info!(
            ">>>> The path of TransactionIndexStorage DB: {}",
            path.to_str().unwrap()
        );
        Ok(Self {
            index_db: StorageBase::new(&path)?,
        })
    }

    // insert or update
    pub(crate) async fn put(
        &self,
        key: &TransactionId,
        value: &TransactionIndexNode,
    ) -> Result<(), DBError> {
        self.index_db.put(key, value).await
    }

    pub(crate) async fn get(
        &self,
        key: &TransactionId,
    ) -> Result<Option<TransactionIndexNode>, DBError> {
        self.index_db.get(key).await
    }

    pub(crate) async fn erase(&self, key: &TransactionId) -> Result<(), DBError> {
        self.index_db.erase(key).await
    }

    pub(crate) async fn exists(&self, key: &TransactionId) -> bool {
        self.index_db.exists(key).await
    }

    pub(crate) async fn flush_database(&self) -> Result<(), DBError> {
        self.index_db.flush_database().await
    }

    pub(crate) async fn get_all_data(&self) -> DbHashMap<TransactionId, TransactionIndexNode> {
        self.index_db.get_all_data().await
    }

    #[cfg(debug_assertions)]
    pub(crate) async fn get_item_number(&self) -> usize {
        self.index_db.get_item_number().await
    }
}
